/* ghead.h is part of VIP program
 * Written by J. Salvador Arias, 2010
 *      CONICET, INSUE, Instituto Miguel Lillo,
 *      Miguel Lillo 205, S.M. de Tucuman (4000)
 *      Tucuman, Argentina
 *      e-mail: jsalarias@csnat.unt.edu.ar
 *
 * VIP is a free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation and
 * Creative Commons.
 *
 * This file and the VIP program is distributed in the hope
 * that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * To view a copy of this license, visit
 * http://creativecommons.org/licenses/GPL/2.0/
 * or send a letter to
 * Creative Commons, 171 Second Street, Suite 300,
 * San Francisco, California, 94105, USA.
 */

#ifndef GENERAL_HEADER_INCLUDED
#define GENERAL_HEADER_INCLUDED

/* ------ General header ------ */
/* The general header is based on glib, as the main project
   is under GTK+.
   But the general part, just uses the non GUI (i.e. glib)
   part of GTK+.
   */
#include <glib.h>

/* ------ Simple types ------ */
/* Synonims of the general types */

#define SINTEGER glong
#define SREAL gdouble
/* Use scounter to declare explicit unsigned values, it is negative for domain errors */
#define SCOUNTER SINTEGER

typedef guint16 SFLAG;      /* Control type */

/* Constant used to start strings */
#define VOIDSTRING "NoStr"

/* ------ Complex types ------ */

/* --- Arrays --- */
/* I use my own array function and structures because the strange behaviuor of the
   glib arrays. */

typedef struct tagINTARRAY INTARRAY;
struct tagINTARRAY {
 SINTEGER* data;
 SCOUNTER len;
 SCOUNTER max;
};

INTARRAY* CreateIntArray (SCOUNTER size);
#define AddToArray(x,y)         (x) -> data [(x) -> len ++] = (y)
#define InsertValToArray(x,y,i) (x) -> data [(i)] = (y)
#define GetFromArray(x,i)       (x) -> data [(i)]
#define GetArraySize(x)         (x) -> len
#define GetArrayMax(x)          (x) -> max
void ShuffleIntArray (INTARRAY* array);
SCOUNTER SearchIndexValue (INTARRAY* array, SINTEGER val);
void DestroyIntArray (INTARRAY* array);

void CopyPtrArray (GPtrArray* dest, GPtrArray* src);
void CopyPtrArrayPart (GPtrArray* dest, GPtrArray* src, SCOUNTER start, SCOUNTER end);
void ShufflePtrArray (GPtrArray* array);
void ShuffleSinglePtrArray (GPtrArray* array, SCOUNTER pos);

GList* NameOnList (gchar* name, GList* list);

/* --- Functions for linked structures --- */
/* Some home-made functions for linked structures, as the standar implementation of glib
   states that does not guarantee to keep the original pointer on additions, removals,
   etc. on lists */

/* Insert an chain-element after prev */
GList* InsertListElement (GList* prev, gpointer data);
/* Deletes a list */
void DestroyList (GList* toDel, gsize sz);
void DestroyLinkElement (GList* toDel, gsize sz);
void DestroyLink (GList* toDel);
/* Put a list after last element of the destination list */
void PutAtListEnd (GList* dest, GList* toPut);
void AddChildren (GNode* toAdd, GNode* anc, GNode* lastSibling);
/* Get next valid node */
GNode* GetNextNode (GNode* actNode);
GNode* GetNextTerm (GNode* actNode);
GNode* GetPrevNode (GNode* actNode);
SFLAG IsDesc (GNode* probe, GNode* anc);

/* ------ Output log */
GString* outLog;

/* ------ Error interface ------ */
/* Used only for user errors (e.g. "bad file format") */
gchar* errorMessage;

/* This function must be defined in the user interface, and must include the RESETERROR macro */
#define RESETERROR g_free (errorMessage)
void OnError ();

#endif
